/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sender;

import common.Packet;
import java.io.File;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 *
 * @author Joe
 */
public class Exercise7 extends javax.swing.JFrame {
    private final int PORT_NUM = 12723;
    private final int CHUNK_SIZE = Packet.MAX_SIZE - Packet.HEADER_SIZE;
    private final int TIMEOUT = 50;
    /**
     * Creates new form Exercise7
     */
    public Exercise7() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        alternatingRadio = new javax.swing.JRadioButton();
        gobacknRadio = new javax.swing.JRadioButton();
        reliableCheckBox = new javax.swing.JCheckBox();
        sendButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        resultsField = new javax.swing.JTextPane();
        jLabel1 = new javax.swing.JLabel();
        filenameField = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        ipField = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        buttonGroup1.add(alternatingRadio);
        alternatingRadio.setSelected(true);
        alternatingRadio.setText("Use Alternating Bit Protocol");

        buttonGroup1.add(gobacknRadio);
        gobacknRadio.setText("Use Go-Back-N Protocol");

        reliableCheckBox.setSelected(true);
        reliableCheckBox.setText("Simulate Unreliable Channel");

        sendButton.setText("Send File");
        sendButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sendButtonActionPerformed(evt);
            }
        });

        resultsField.setEditable(false);
        jScrollPane1.setViewportView(resultsField);

        jLabel1.setText("Filename:");

        filenameField.setText("rocket.jpg");

        jLabel2.setText("IP Address: ");

        ipField.setText("138.246.36.61");
        ipField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ipFieldActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(ipField))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reliableCheckBox)
                            .addComponent(gobacknRadio)
                            .addComponent(alternatingRadio)
                            .addComponent(jLabel1))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(filenameField, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(sendButton, javax.swing.GroupLayout.PREFERRED_SIZE, 157, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(alternatingRadio)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(gobacknRadio)
                        .addGap(4, 4, 4)
                        .addComponent(reliableCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(filenameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sendButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(ipField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(jScrollPane1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendButtonActionPerformed
        // Clear the last messages from the UI
        resultsField.setText("");
        // Get the file
        File file = new File(filenameField.getText());
        try {
            // Resolve the receiver's address and make the UDP socket.
            InetAddress address = InetAddress.getByName(ipField.getText());
            DatagramSocket socket = new DatagramSocket();
            socket.connect(address, PORT_NUM);
            socket.setSoTimeout(TIMEOUT);
            // Resolve which protocol to use, default to alternating protocol
            PacketSender sender = new Alternating(socket);
            if (gobacknRadio.isSelected())
            {
                sender = new GoBackN(socket);
            }
            // Break the file into packets
            ArrayList packets = makePackets(Files.readAllBytes(file.toPath()));
            // Send the packets
            sender.send(packets, reliableCheckBox.isSelected());
            // Find out what happened
            showResults(sender.getResults());
            
           // byte[] data = new Packet("Hello".getBytes(), (byte) 1, Packet.NORMAL_FLAG).getRaw();
            //socket.send(new java.net.DatagramPacket(data, data.length));
            // Clean up
            socket.close();
        } catch (IOException ex) {
            Logger.getLogger(Exercise7.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_sendButtonActionPerformed

    private void ipFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ipFieldActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_ipFieldActionPerformed
    private ArrayList<Packet> makePackets(byte[] fileData)
    {
        ArrayList<Packet> packets = new ArrayList();
        // Add a first packet containing the filename
        Packet first = new Packet(filenameField.getText().getBytes(), (byte) 0, 
                Packet.FILENAME_FLAG);
        System.out.println(new String(filenameField.getText().getBytes()));
        packets.add(first);
        // Calculate the number of packets to make
        int numPackets = fileData.length / CHUNK_SIZE;
        // Copy the file's byte data into packet objects
        int i;
        for (i = 0; i < numPackets; i++)
        {
            Packet p = new Packet(java.util.Arrays.copyOfRange(
                    fileData, i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE),
                    (byte) ((i + 1)% 2), Packet.NORMAL_FLAG);
            packets.add(p);
        }
        if (fileData.length % CHUNK_SIZE > 1)
        {
            Packet p = new Packet(java.util.Arrays.copyOfRange(
                    fileData, i * CHUNK_SIZE, fileData.length),
                    (byte) ((i + 1) % 2), Packet.NORMAL_FLAG);
            packets.add(p);
        }
        // Add the last packet containing the end of transmission flag
        Packet last = new Packet(filenameField.getText().getBytes(), (byte) 0, 
                Packet.END_FLAG);
        packets.add(last);
        return packets;
    }
    private void showResults(Results results)
    {
        resultsField.setText("Sent: " + results.sent + "\n" +
                "Resent: " + results.resent + "\n" + 
                "Known dropped: " + results.dropped + "\n" + 
                "Known duplicated: " + results.duplicated + "\n" + 
                "Known corrupted: " + results.corrupted + "\n");
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

            /* Create and display the form */
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Exercise7.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(Exercise7.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(Exercise7.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Exercise7.class.getName()).log(Level.SEVERE, null, ex);
        }

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Exercise7().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JRadioButton alternatingRadio;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JTextField filenameField;
    private javax.swing.JRadioButton gobacknRadio;
    private javax.swing.JTextField ipField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JCheckBox reliableCheckBox;
    private javax.swing.JTextPane resultsField;
    private javax.swing.JButton sendButton;
    // End of variables declaration//GEN-END:variables
}
